package com.hmall.api.client.fallback;

import com.hmall.api.client.ItemClient;
import com.hmall.api.dto.ItemDTO;
import com.hmall.api.dto.OrderDetailDTO;
import com.hmall.common.utils.CollUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;

import java.util.Collection;
import java.util.List;

@Slf4j
public class ItemClientFallbackFactory implements FallbackFactory<ItemClient> {

    //熔断和fallback是一样,只是熔断和fallback的触发条件不同,熔断是服务调用失败,会触发熔断,fallback是服务调用成功,但是服务返回失败,会触发fallback
    //熔断后的处理,就是fallback,如果服务调用失败,就会触发熔断,然后走fallback,如果服务调用成功,但是服务返回失败,也会触发fallback
    @Override
    public ItemClient create(Throwable cause) { //这里的 Throwable cause就是feign请求失败的异常,可以通过这个异常记录日志
        //之所以返回的是ItemClient对象,是因为此方法就是对这个fegin请求的备用方案
        //正常的服务没问题返回的也正常就走正常逻辑,如果服务出问题,就会降级走这个方法
        //所以这里返回的跟openfeign的接口一样,只是做的处理不同,这个是降级方案
        // (可以看ItemClient接口调用,请求发完成功返回,调用的时候都是注入ItemCliemt,然后调用接口,所以这里返回的也是ItemCliemt,到时候写代码也是用它调用接口)
        return new ItemClient() {
            @Override
            public List<ItemDTO> queryItemByIds(Collection<Long> ids) {
                log.error("查询商品失败！", cause);
                return CollUtils.emptyList(); //查询失败也不会报错,返回空集合只是让他查不到数据.这就是兜底方案
            }

            @Override
            public void deductStock(List<OrderDetailDTO> items) {
                log.error("扣减商品库存失败！", cause);
                throw new RuntimeException(cause);
            }
        };
    }
}
